#!/bin/bash -
#===============================================================================
#
#          FILE: pxeserver.sh
#
#         USAGE: ./pxeserver.sh
#
#   DESCRIPTION: 兆芯UOS系统版pxe服务器搭建
#
#       OPTIONS: ---
#  REQUIREMENTS: ---
#          BUGS: ---
#         NOTES: ---
#        AUTHOR: 张培培 (ZHANG), zimingzpp@qq.com
#  ORGANIZATION: 
#       CREATED: 2020年09月14日 19时48分28秒
#      REVISION:  ---
#===============================================================================

set -o nounset                                  # Treat unset variables as an error

set -e

_red(){
    printf '\033[1;31;31m%b\033[0m' "$1"
}

_green(){
    printf '\033[1;31;32m%b\033[0m' "$1"
}

_error(){
    _red "$1"
    printf "\n"
    exit 1
}

_printargs(){
    printf -- "%s" "$1"
    printf "\n"
}

is_root(){
    if [[ "$USER" != "root" ]]; then
        _error "ERROR! 请用root用户执行脚本!"
    fi
}
_info(){
    _printargs "$@"
}

get_opsy(){
    [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
    [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
}

is_digit(){
    local input="$1"
    if [[ "$input" =~ ^[0-9]+$ ]]; then
        return 0
    else
        return 1
    fi
}

error_detect_depends(){
    local command="$1"
    local work_dir=$(pwd)
    local depend=$(echo "$1" | awk '{print $4}')
    _info "Installing package ${depend}"
    ${command} > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        distro=$(get_opsy)
        version=$(cat /proc/version)
        architecture=$(uname -m)
        mem=$(free -m)
        disk=$(df -ah)
        cat >> ${cur_dir}/error.log<<EOF
        Errors Detail:
        Distributions:${distro}
        Architecture:${architecture}
        Version:${version}
        Memery:
        ${mem}
        Disk:
        ${disk}
        Issue:failed to install ${depend}
EOF
        echo
        echo "+------------------+"
        echo "|  ERROR DETECTED  |"
        echo "+------------------+"
        echo "安装软件 ${depend} 失败."
        echo "完整信息请看 ${cur_dir}/error.log"
        echo "请检测计算机是否联网"
        exit 1
    fi
}


get_ip(){
    local ipv4=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | \
    egrep -v "^169|^127|255$" | head -n 1 )
    [ -z "${ipv4}" ] && ipv4=$( wget -qO- -t1 -T2 ipv4.icanhazip.com )
    [ -z "${ipv4}" ] && ipv4=$( wget -qO- -t1 -T2 ipinfo.io/ip )
    printf -- "%s" "${ipv4}"
}

check_os(){
    if ! grep -Eqi "uos" /etc/os-release; then
        _error "请使用uos系统运行此脚本！"
    fi
}

mk_tftpboot(){
    if [ ! -d /tftpboot/pxelinux.cfg ]
    then
    	mkdir -p /tftpboot/pxelinux.cfg
    else
        rm -rf /tftpboot
        mkdir -p /tftpboot/pxelinux.cfg
    fi
    if [ ! -d /mnt/uos ]
    then
    	mkdir -p /mnt/uos
    else
        umount /mnt/uos 2>/dev/null || echo ""
        rm -rf /mnt/uos
        mkdir -p /mnt/uos
    fi
    if mount /dev/sr0 /mnt/uos &>/dev/null; then
        echo "镜像加载成功！"
    else
        read -p "没有检测到光盘，是否手动指定光盘位置?[Y/n]" location
        if [[ "$location" == "" || "$location" == "y" || "$location" == "Y" ]]; then
            while true; do
            read -p "请输入兆芯UOS镜像的具体位置:" iso
                if [ -f "$iso" ]; then
                    mount $iso /mnt/uos >/dev/null 2>&1
                    break
                else
                    echo "文件不存在！"
                    continue
                fi
            done
        else
            exit 1
        fi
    fi
}

file_copy(){
    if  grep -Eqi "uos|uniontech\ os\ 20" /mnt/uos/boot/grub/grub.cfg || [[ -d /mnt/uos/boot/grub/x86_64-efi ]]; then
        cp -r /mnt/uos/isolinux/. /tftpboot
        cp /mnt/uos/live/vmlinuz /tftpboot
        cp /mnt/uos/live/initrd.lz /tftpboot
    else
        _error "错误！请使用兆芯版uos安装盘，重新运行此脚本!"
    fi
    if [ ! -f ./pxelinux.0 ]; then
        _error "错误! 请保证pxelinux.0文件与此脚本在同一文件夹下!"
    else
        cp ./pxelinux.0 /tftpboot
    fi

    echo "
    default vesamenu.c32
    timeout 50
    menu autoboot Starting Linux install in # second{,s}. Press any key to interrupt.
    menu clear
    menu title UOS20 
    label UOS
      menu label Start UOS20 
      kernel vmlinuz
      append initrd=initrd.lz boot=live livecd-installer netboot=nfs nfsroot=$(get_ip):/mnt/uos locale=zh_CN.UTF-8
    ">/tftpboot/pxelinux.cfg/default
}

dhcp_config(){
    local inet
    local IP=$(get_ip)
    local broadcast=${IP%.*}.255
    local poolstart
    local poolstop
    local SUBNET=${IP%.*}.0
    
    while true; do
        read -p "请输入作为pxe服务器的网卡名称:" inet
        read -p "dhcp地址池的起始地址是(默认是: 3):" start
        read -p "dhcp地址池的末尾地址是(默认是: 30):" stop

        if [[ "$start" == "" ]]; then
            start=3
        fi
        if [[ "$stop" == "" ]]; then
            stop=30
        fi
        if  ! is_digit "$start" || ! is_digit "$stop" ; then
            _info "$(_red 错误！请输入数字地址)"
            continue
        fi
        if [[ "$start" -gt "$stop" ]]; then
            _info "$(_red 错误！输入起始和末尾地址有误！)"
            continue
        fi
        if [[ "$start" -lt 1  ||  "$stop" -gt 254 ]]; then
            _info "$(_red 错误！输出的地址超出范围)"
            continue
        fi
        poolstart=${IP%.*}.$start
        poolstop=${IP%.*}.$stop
        break
    done
    echo 'INTERFACESv4="'$inet'"'>/etc/default/isc-dhcp-server
    echo "
    allow booting;
    allow bootp;
    subnet $SUBNET netmask 255.255.255.0 { 
    	range $poolstart $poolstop;   
    	option routers $IP;  
    	option broadcast-address $broadcast;  
    	option domain-name-servers $IP; 
    	default-lease-time 600;  
    	max-lease-time 7200;  
    	next-server $IP;  
    	filename \"pxelinux.0\";   
    }">/etc/dhcp/dhcpd.conf
    systemctl restart isc-dhcp-server >/dev/null 2>&1
}

tftp_config(){
    echo '
    TFTP_USERNAME="tftp"
    TFTP_DIRECTORY="/tftpboot"
    TFTP_ADDRESS="0.0.0.0:69" 
    TFTP_OPTIONS="-l -c -s"
    '>/etc/default/tftpd-hpa
    systemctl restart tftpd-hpa >/dev/null 2>&1
}

nfs_config(){
    echo "
    /mnt/uos *(ro)">/etc/exports
    systemctl restart nfs-kernel-server >/dev/null 2>&1
    chmod -R 777 /tftpboot
}

pre_settings(){
    is_root
#    check_os
    mk_tftpboot
    file_copy
}

install_dhcp_server(){
    if [[ -f /var/run/dhcp.pid ]]; then
        rm -rf /var/run/dhcp.pid
    fi
    _info "正在更新系统..."
    apt-get -y update > /dev/null 2>&1
    _info "正在安装配置DHCP服务器..."
    error_detect_depends "apt-get -y install isc-dhcp-server"> /dev/null 2>&1
    dhcp_config
    _info "ok"
}

install_tftpd_server(){
    _info "正在安装配置TFTP服务器..."
    error_detect_depends "apt-get -y install tftpd-hpa"> /dev/null 2>&1
    tftp_config
    _info "ok"
}

install_nfs_server(){
    _info "正在安装配置NFS服务器..."
    error_detect_depends "apt-get -y install nfs-kernel-server"> /dev/null 2>&1
    nfs_config
    _info "ok"
}

main(){
    pre_settings
    install_dhcp_server
    install_tftpd_server
    install_nfs_server
    _info "$(_green PXE服务器已经部署完成！)"
}


main "$@" 2>&1
